package controllers

import (
	"github.com/revel/revel"
	"gopkg.in/mgo.v2/bson"
	"waterblabla/app/models"
)

type Station struct {
	Controller
}

func (c Station) AddStation() revel.Result {
	type Req struct {
		Sid            string `,inline json:"sid" valid:"Required"`
		models.Station `,inline`
		ProviderIDs    []string `json:"providerIDs" valid:"Required"`
	}
	var req Req
	// parse
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}
	// validate qid&sid
	qs := models.QS{req.Qid, req.Sid}
	if err := qs.Validate(); err != nil {
		return c.RenderResult(err)
	}
	// TODO: how to check station redundancy

	// get providers
	if err := models.GetProviders(req.ProviderIDs, &req.Station.Providers); err != nil {
		return c.RenderResult(err)
	}
	// add station
	stationID, err := models.AddStation(&req.Station)
	if err != nil {
		return c.RenderResult(err)
	}
	return c.RenderResult(struct {
		StationID string `json:"stationID"`
	}{stationID})
}

func (c Station) GetStations() revel.Result {
	var qs models.QS
	if err := models.ParseBodyAndValidate(c.body, &qs); err != nil {
		return c.RenderResult(err)
	}

	var stations []models.Station
	if err := models.GetStations(qs.Qid, &stations); err != nil {
		return c.RenderResult(err)
	}

	return c.RenderResult(stations)
}

func (c Station) UpdateStation() revel.Result {
	type Req struct {
		Sid            string `,inline json:"sid" valid:"Required"`
		models.Station `,inline`
		ProviderIDs    []string `json:"providerIDs" valid:"Required"`
	}
	var req Req
	// parse
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}
	// validate qid&sid
	qs := models.QS{req.Qid, req.Sid}
	if err := qs.Validate(); err != nil {
		return c.RenderResult(err)
	}
	// get providers
	if err := models.GetProviders(req.ProviderIDs, &req.Station.Providers); err != nil {
		return c.RenderResult(err)
	}
	if err := models.UpdateStation(&req.Station); err != nil {
		return c.RenderResult(err)
	}

	return c.RenderResult(nil)
}

// TODO: deprecated
func (c Station) GetStationInfo() revel.Result {
	type Req struct {
		models.QS `,inline`
		StationID string `json:"stationID"`
	}
	var req Req
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}

	var station models.Station
	if err := models.GetMyStation(req.QS.Qid, req.StationID, &station); err != nil {
		return c.RenderResult(err)
	}

	return c.RenderResult(station)
}

// TODO: deprecated
func (c Station) GetProducts() revel.Result {
	type Req struct {
		models.QS `,inline`
		StationID string `json:"stationID"`
	}
	var req Req
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}
	var products []models.Product
	// TODO: limit count
	if err := models.GetStationProducts(req.QS.Qid, req.StationID, &products); err != nil {
		return c.RenderResult(err)
	}
	return c.RenderResult(products)
}

func (c Station) GetPostman() revel.Result {
	type Req struct {
		models.QS `,inline`
		StationID string `json:"stationID"`
	}
	var req Req
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}
	var men []*models.Postman
	if err := models.GetPostman(req.QS.Qid, req.StationID, &men); err != nil {
		return c.RenderResult(err)
	}
	return c.RenderResult(men)
}

func (c Station) AddPostman() revel.Result {
	type Req struct {
		models.QS `,inline`
		StationID string         `json:"stationID"`
		Postman   models.Postman `json:"postman" valid:"Required"`
	}
	var req Req
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}

	return c.RenderResult(models.AddPostman(req.QS.Qid, req.StationID, req.Postman))
}

func (c Station) RmPostman() revel.Result {
	type Req struct {
		models.QS `,inline`
		StationID string         `json:"stationID"`
		Postman   models.Postman `json:"postman" valid:"Required"`
	}
	var req Req
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}

	return c.RenderResult(models.RmPostman(req.QS.Qid, req.StationID, req.Postman))
}

func (c Station) UpdatePostman() revel.Result {
	type Req struct {
		models.QS `,inline`
		StationID string         `json:"stationID" valid:"Required"`
		Postman   models.Postman `json:"postman" valid:"Required"`
	}
	var req Req
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}

	return c.RenderResult(models.UpdatePostman(req.QS.Qid, req.StationID, req.Postman))
}

func (c Station) Stats() revel.Result {
	type Req struct {
		models.QS `,inline valid:"Required"`
		From      int64 `bson:"from" json:"from"   valid:"Required"`
		To        int64 `bson:"to" json:"to"  valid:"Required"`
	}
	var req Req
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}

	count, err := models.TotalStation(req.Qid, req.From, req.To)
	if err != nil {
		return c.RenderResult(0)
	}
	return c.RenderResult(count)
}

func (c Station) StatsPostman() revel.Result {
	type Req struct {
		models.QS `,inline valid:"Required"`
		Postman   []string `json:"postman"`
		From      int64    `json:"from"   valid:"Required"`
		To        int64    `json:"to"  valid:"Required"`
	}
	var req Req
	if err := models.ParseBodyAndValidate(c.body, &req); err != nil {
		return c.RenderResult(err)
	}

	var result []bson.M
	if err := models.StatsPostman(req.Qid, req.From, req.To, req.Postman, &result); err != nil {
		return c.RenderResult(err)
	}
	return c.RenderResult(result)
}
